home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
edit
/
aaem95ma.zip
/
DISPLAY.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-24
|
14KB
|
246 lines
/* This file is DISPLAY.CC */
#include "em.h"
char*offscreen="cursor is one column off screen";
static byte current_buffer=1;
/*----- if this line should have its eol char printed */
int line::showeol(){if(no_cr()) return LF; if(!n) return CR;
reg char C=s[n-1]; if(C!=' ') if(C!='I'-64) if(C) if(C!='\377') if(C!=CR)
if(mark(this,n)!=B->col.Reg.beg) if(!next?:mark(next,0)!=B->col.Reg.end)
return 0;
return CR;}
/*-----*/
void refreshscreen(){int i; buffer*BB=B; current_buffer=0;
for(i=0;i<nwindows;i++)if((B=window[i])->nrows)if(i!=currentwindow)B->display();
current_buffer=1; (B=window[currentwindow])->display(); B=BB;}
/*-----*/
void buffer::redraw_info() {int i; char cw[512];
pr(cw," AAEMACS: %s",name); if(bound.n) pa(cw," (%k)",&bound);
for(i=0;i<gp_Cols;i++) Sl[lastrow].sa[i]=sch(' ',Attrib(Magenta,White));
if(changed) cw[0]='*'; ::displayn(cw,lastrow,0,Magenta,White);
if(start.c) scr(lastrow,1)=17+256*(Red+16*White); Sl[lastrow].ok=1;}
/*----- on ith row of screen. To (SL->nc-1)th col */ /* 9==tab */
void line::display(int i){screenline *SL=&Sl[i];
if(this==line0) {gp_clear(i); SL->ok=0; return;} if(!la()) if(SL->ok) return;
char tt=B->tabtype,*S=s; byte C;
int sheol=showeol(),j=0,k=0,spdue=0,geeup=B->start.c,whoa=gp_Cols+geeup;
uns short at=gp_Attr<<8, *Screen=SL->sa-geeup, sc;
OFFLEFT: if(!tt) j=k=geeup; if(j>=geeup) goto NEXTCHAR;
if(spdue) {spdue--; C=' ';} else if(k<n) C=S[k++]; else goto EOL; /* get char */
if(C==9) if(tt) spdue=sptotab(j); j++; goto OFFLEFT;
NEXTCHAR: if(spdue) {spdue--; C=' ';} else if(k<n) C=S[k++]; /* get char */
else {if(k>n ?: !sheol) goto EOL; C=sheol; k++;}
if(j==whoa) {Screen[j-1]=sch(16,(gp_Attr&~15)|Red); goto EOL;}
if(C==9)if(tt) {Screen[j]=(tt==1?' ':9)|at; spdue=sptotab(j);j++;goto NEXTCHAR;}
Screen[j++]=C|at; goto NEXTCHAR;
EOL: if(j<=geeup) {Screen[geeup]=(sheol?:CR)|at; j=geeup+1;}
k=(SL->nc+geeup)<?whoa; sc=' '|at; while(k>j) Screen[--k]=sc; SL->nc=j;
SL->ok=1; la(0);}
/*-----*/
void buffer::display(){reg int h,i,j; int k,l,m,n,p,u,v,w,N,P; char *T;
line *L,*M; short attr; screenline*S; if(longlines) {dispfold(); return;}
#define forwin(S,i) for(i=row1;S=Sl+i,i<lastrow;i++)
if(this!=B) MOAN("BUG: tried to display non-current buffer"); if(!nrows) return;
forwin(S,i) if(S->buf!=this) {S->ok=0; S->buf=this;}
char redrawinfo=Sl[lastrow].buf!=this?:!Sl[lastrow].ok?:changed!=oldch;
j=-1; L=start.r; forwin(S,i) {if((S->nl=L)==dot.r) j=i; if(!(L=L->next)) break;}
if(j<0) {for(L=dot.r,i=(nrows-1)/2;i>0;i--,L=L->prev) if(!L->prev) break;
start.r=L; forwin(S,i) {if((S->nl=L)==dot.r) j=i; if(!(L=L->next)) break;}}
for(i++;i<lastrow;i++) Sl[i].nl=line0; dot.r->dotty();
cursor.c=i=dot.r->to_scrcolno(dot.c); cursor.r=j; k=start.c=startc;
if(i<0?1:i>=gp_Cols) { /* move display to left or right? */
if(i!=gp_Cols?0:dot.c!=dot.r->n?0:!dot.r->showeol()) {
if(current_buffer) Moan=offscreen;}
else {forwin(S,i) S->ok=0; /* must redraw */
j=gp_Cols; dotcc=-1; dot.r->dotty(); k=dotcc+start.c;
startc=start.c=k<j ?0: (i=(k-j/4)/(j/2),i*(j/2)); cursor.c=k-start.c;}}
forwin(S,i) if(L=S->l) L->sl=line_notshown;
forwin(S,i) S->nl->sl=i; line0->sl=line_notshown; /*reset .sl's for new screen*/
forwin(S,i) if(!S->ok ?1: S->l!=S->nl) {S->nc=gp_Cols; S->nl->la(1);}
forwin(S,i) (S->l=S->nl)->display(i);
if(L=col.Reg.beg.r) {h=Attrib(col.fg,col.bg);
u=L->to_scrcolno(col.Reg.beg.c)>?0;
for(M=0;L;L=L->next) if(L==col.Reg.end.r) {M=L; break;} L=col.Reg.beg.r;
if(M) do {m=L==M;
if((k=L->sl)!=line_notshown) {
Sl[k].ok=0; v=(m?L->to_scrcolno(col.Reg.end.c):Sl[k].nc)<?gp_Cols;
T=(char*)Sl[k].sa+1; for(i=u;i<v;i++) T[i<<1]=h;}
u=0; if(m) break;} while(L=L->next);
col.Reg.beg=mark(); col.Reg.end=mark();}
Sl[lastrow].l=modeline; oldch=changed; emptydustbin();
if(redrawinfo) redraw_info(); cursor.c<?=gp_Cols-1; gp_cursor(cursor);
/*** if any change of window sizes, Sl[i].ok=0 on affected lines ***/
/*** ditto for all lines of any buffer that I get rid of ***/ }
/*----- on ith etseq row of screen. 9==tab. Returns next free screen lineno */
int line::dispfold(int i) {if(i>=B->lastrow) return i; screenline *SL=Sl+i;
int J,dc=B->dot.c<?B->dot.r->n; line*dr=B->dot.r;
if(this==line0) {if(i>=B->row1) {gp_clear(i); SL->ok=0;} return i+1;} sl=i;
if(!la()) if(i>=B->row1) if(SL->ok) if(SL->l==this) if(!SL->lp) if(this!=dr){
while(SL->l==this) SL++; return SL-Sl;} /* line unchanged & unmoved */
byte C; char*S=s,tt=B->tabtype; uns short sc;
int I=i,m,sheol=showeol(),N=sheol?n:n-1; /*** call dotty() first ***/
uns short *Sc=screen+i*gp_Cols,*geeup=screen+B->row1*gp_Cols,*whoa=Sc+gp_Cols,
at=gp_Attr<<8; int j=0,k=0,spdue=0; if(Sc>=geeup) goto NEXTCHAR;
OFFTOP:
if(spdue){spdue--;C=' ';}else if(k>N)return I+1; else C=k==n?(k++,sheol):S[k++];
if(C==9?tt:0) {sc=(tt==1?' ':9)|at; spdue=sptotab(j);} else sc=C|at; j++;Sc++;
if(Sc>=whoa) if(k<=N) {I++; if(Sc>=geeup) goto RED; SL++; whoa+=gp_Cols; Sc+=2;}
goto OFFTOP;
NEXTCHAR: if(dr==this) if(dc==k) cursor=gp_cur(I,Sc-whoa+gp_Cols);
if(spdue){spdue--;C=' ';}else if(k>N) goto EOL; else C=k==n?(k++,sheol):S[k++];
if(C==9?tt:0) {*Sc++=sc=(tt==1?' ':9)|at; spdue=sptotab(j);} else *Sc++=sc=C|at;
j++;
if(Sc>=whoa) if(k<=N) {
sc=Sc[-1]; Sc[-1]=sch(16,(gp_Attr&~15)|Red); SL->nc=gp_Cols; SL->nc=gp_Cols;
SL->l=this; SL->lp=I-i; SL->lc=k-1; if(++I>=B->lastrow) return I;
RED: if(dr==this) if(dc==k-1) cursor=gp_cur(I,Sc-whoa+1); SL++;
whoa+=gp_Cols; *Sc++=sch(17,(gp_Attr&~15)|Red); *Sc++=sc;} goto NEXTCHAR;
EOL: whoa=screen+(j=I*gp_Cols)+SL->nc; sc=' '|at; SL->nc=Sc-j-screen; SL->ok=1;
la(0); SL->l=this; SL->lp=I-i; SL->lc=n; while(Sc<whoa) *Sc++=sc; return I+1;}
/*----- screen location of char within line */
int linewhere(mark M){int c,k,z; if(!M.r) return 0;
z=M.r->showeol()?M.r->n:M.r->n-1; /* # chars in line (with eol if displayed) */
c=M.r->to_tabexp(M.c<?M.r->n); /* char position in line as displayed */
return !c ?0: c+2*((c-(M.c>=z?2:1))/(gp_Cols-2));}
/*----- screen location of mark *//* relies on screen lines being consecutive */
static int scrwhere(mark M,int defolt=0){int k;
if(!M.r ?: M.r==line0 ?: (k=M.r->sl)==line_notshown) return defolt;
return k*gp_Cols+linewhere(M);}
/*----- how many parts in folded line (up to c, if c>=0) */
int line::nparts(int c/*=-1*/) {return 1+linewhere(mark(this,c<0?n:c))/gp_Cols;}
/*----- display buffer in fold-long-lines mode */
void buffer::dispfold(int d/*=0*/){reg int h,i,j; int jj,k,l,m,n,p,u,v,w,N,P;
char *T; line *L,*M; short attr; screenline*S; char fold=B->longlines;
if(this!=B) MOAN("BUG: tried to display non-current buffer"); if(!nrows) return;
for(i=row1;i<=lastrow;i++) if(Sl[i].buf!=this) {Sl[i].ok=0; Sl[i].buf=this;}
char redrawinfo=!Sl[lastrow].ok?1:(changed!=oldch); start.c=startc; stback+=d;
M=start.r; while(M->next?(j=stback-M->nparts())>=0:0) {M=M->next; stback=j;}
while(stback<0?(L=M->prev):0) stback+=(M=L)->nparts(); stback>?=0; start.r=M;
forwin(S,i) {if(L=S->l) L->sl=line_notshown; if(!S->ok) S->nc=gp_Cols;}
L=start.r; i=row1-stback; S=Sl+i; cursor.r=cursor.c=255; dot.r->dotty();
while(i<lastrow) {i=L->dispfold(i); L=L->next?:line0;}
if(d) if(L==line0) {d=0; dot.r=text.prev; dot.c=0;} /* off end of buffer */
if(d){i=row1+nrows/2; dot=mark(L=Sl[i].l,Sl[i].lc);dotcc=-1;L->dispfold(L->sl);}
else {
if(refresh?:cursor.r==255) { /* dot not on screen */
forwin(S,i) {if(L=S->l) L->sl=line_notshown; S->ok=0; S->nc=gp_Cols;}
L=dot.r; j=L->nparts(dot.c<?L->n); i=row1+nrows/2-j+1; refresh=0;
while(L->prev?i>row1:0) i-=(L=L->prev)->nparts();
if(i>row1) {i=row1; L=B->text.next;} stback=row1-i; start=mark(L,0);
while(i<lastrow) {i=L->dispfold(i); L=L->next?:line0;}}}
if(L=col.Reg.beg.r) {h=Attrib(col.fg,col.bg);
for(M=0;L;L=L->next) if(L==col.Reg.end.r) {M=L; break;} L=col.Reg.beg.r;
if(M) for(i=0;L;L=L->next,i++) {m=L==M;
if((k=L->sl)!=line_notshown) {S=Sl+k;
u=i==0?scrwhere(col.Reg.beg,row1*gp_Cols):(k>?row1)*gp_Cols;
while(S->l==L) S++->ok=0; S--;
v=m?scrwhere(col.Reg.end,lastrow*gp_Cols):((S-Sl)*gp_Cols+S->nc);
u>?=row1*gp_Cols; v<?=lastrow*gp_Cols; u*=2; v*=2;
T=(char*)screen+1; for(j=u;j<v;j+=2) if(T[j]!=Red) T[j]=h;}
if(m) break;}
col.Reg.beg=mark(); col.Reg.end=mark();}
Sl[lastrow].l=modeline; oldch=changed; emptydustbin();
if(redrawinfo) redraw_info();
if(cursor.c>=gp_Cols) {Moan=offscreen; cursor.c=gp_Cols-1;} gp_cursor(cursor);
/*** if any change of window sizes, Sl[i].ok=0 on affected lines ***/
/*** ditto for all lines of any buffer that I get rid of ***/ }
/*----- display string s on screen line n (displayn = do not clear to eol) */
int displayn(val T,int n,int c,int fc/*=White*/,int bc/*=Black*/){
reg int i,j; short attr=Attrib(fc,bc); uns short*SL=Sl[n].sa;
for(i=(j=T.n<?(gp_Cols-c))-1;i>=0;i--) SL[c+i]=sch(T.s[i],attr); Sl[n].ok=0;
return j+c;} /* returns next free col */
/*-----*/
int displayn(char*s,int n,int c,int fc/*=White*/,int bc/*=Black*/){
return displayn(val(s,strlen(s)),n,c,fc,bc);}
/*-----*/
void display(val T,int n,int c,int fc/*=White*/,int bc/*=Black*/){
int i=displayn(T,n,c,fc,bc); gp_clear(n,i,gp_Cols-1);}
/*-----*/
void display(char*s,int n,int c,int fc/*=White*/,int bc/*=Black*/){
int i=displayn(val(s,strlen(s)),n,c,fc,bc); gp_clear(n,i,gp_Cols-1);}
/*----------*//* MOUSE */
#include <dos.h>
Mouse Jerry; Regs R;
/*-----*/
void Mouse::show(){R.x.ax=1; Int(0x33); visible=1;};
void Mouse::hide(){R.x.ax=2; Int(0x33); visible=0;};
void Mouse::read(){R.x.ax=3; Int(0x33); x=R.x.cx>>3; y=R.x.dx>>3;};
void Mouse::move(int Y,int X){
R.x.ax=4; R.x.cx=X*8+4; R.x.dx=Y*8+4; Int(0x33); read();};
void Mouse::range(int YE,int XE){
R.x.ax=7; R.x.cx=0; R.x.dx=XE*8-1; Int(0x33); xe=XE;
R.x.ax=8; R.x.cx=0; R.x.dx=YE*8-1; Int(0x33); ye=YE;}
Mouse::~Mouse(){hide(); settrap(0,(void (*)(Regs *))(0));};
void Mouse::operator=(mousestate&m){move(m.x,m.y);
if(m.visible) show(); else hide(); mc=m.mc; bd=m.bd; range(m.ye,m.xe);}
/*-----*/
void mousestate::operator=(Mouse&m){
x=m.x; y=m.y; visible=m.visible; mc=m.mc; bd=m.bd; xe=m.xe; ye=m.ye;};
/*-----*/
/* Simulate a software interrupt from protected mode. Like int86() but calls
DPMI services and so doesn't need DOS extender, only a DPMI server. */
int int86dpmi(int intno) {REGS r,s; Regs S; S=R;
S.x.ss=S.x.sp=0; /* DPMI server is to provide stack for interrupt call */
S.x.flags=0; /* he likeliest forgot to zero the flags */
/* I replaced the call of _go32_dpmi_simulate_int() by a copy of its body here*/
r.h.bl=intno; r.h.bh=0; r.x.cx=0; r.x.di=(int)&S;
if(intno==0x21 && S.x.ax==0x4b00) { /* call a child process */
r.x.ax=0xff0a; int86(0x21,&r,&s);}
else {r.x.ax=0x0300; int86(0x31,&r,&s);}
R=S; return R.d.eax;}
/*-----*/
Regs cb_regs; static _go32_dpmi_seginfo cb_info; /* for callback */
/*-----*/
void Mouse::settrap(uns int mask,void (*func)(Regs *)) {REGS r;
/* This is tricky in protected-mode. We must allocate a real-mode wrapper
function which will be called by the mouse driver, and which in turn will
switch to protected-mode and call our protected-mode handler function. */
if(!Jerry.nbuttons) return;
if(!func) {Jerry.handlerInstalled=0; /* remove handler */
_go32_dpmi_free_real_mode_callback(&cb_info); R.x.dx=R.x.es=0;}
else { /* Allocate real-mode call-back. Find real-mode address of handler */
cb_info.pm_offset=(uns long)func; Jerry.handlerInstalled=1;
if(_go32_dpmi_allocate_real_mode_callback_retf(&cb_info,&cb_regs)) return;
R.x.dx=cb_info.rm_offset; R.x.es=cb_info.rm_segment;}
R.x.ax=12; R.x.cx=mask; int86dpmi(0x33);}
/*-----*/
void event(Regs*R){char events;
events=R->x.ax; Jerry.buttons=R->x.bx&7; Jerry.x=R->x.cx/8; Jerry.y=R->x.dx/8;
if(events&1&Jerry.mc) inject(-mousemove); /* mouse moved */
#define J Jerry /* buttons pressed */
if(events&0x02) {if(J.bd) inject(-lbuttond); J.ldx=J.x; J.ldy=J.y;}
if(events&0x20) {if(J.bd) inject(-mbuttond); J.mdx=J.x; J.mdy=J.y;}
if(events&0x08) {if(J.bd) inject(-rbuttond); J.rdx=J.x; J.rdy=J.y;}
if(events&0x04) inject(-lbutton); /* buttons released */
if(events&0x40) inject(-mbutton);
if(events&0x10) inject(-rbutton);}
#undef J
/*-----*/
void Mouse::setup() {_go32_dpmi_seginfo info;
/* Check if a mouse is installed. If it is, then somebody
(the mouse driver) should have grabbed the 33h interrupt vector. */
buttons=nbuttons=handlerInstalled=visible=0;
/* if(_go32_dpmi_get_real_mode_interrupt_vector(0x33,&info)) return;
if(!info.rm_segment) if(!info.rm_offset) return; /* exit if no mouse driver */
R.x.ax=0; Int(0x33); /* Initialise mouse driver */
if(!(R.x.ax&0xffff)) return; /* no mouse found */
nbuttons=R.x.bx&0xff; move(0,0); mc=bd=0; hide(); range(gp_Cols,gp_Rows);}
/*-----*/
KF(mouse_mode) {if(!Jerry.mc) {B->olddot=B->dot; Jerry.mc=Jerry.bd=1;}
else if(B->dot==B->olddot) Sl[B->lastrow].ok=Jerry.mc=Jerry.bd=0;
else {B->Mark(1)=B->olddot; B->Mark(2)=B->dot;}}
/*-----*/
KF(setolddot) {B->olddot=B->dot;}
/*-----*/
KF(mouse_move) {int i,n,x=oldmx,y=oldmy; line*P;
Z: if(!(n=Jerry.y-y)) if(x==Jerry.x) goto Y;
if(B->longlines) if(Jerry.x>=gp_Cols) Jerry.move(Jerry.y,gp_Cols-1);
if(B->longlines) godownpart(val(n,_int),val(Jerry.x,_int));
else {
if(n>=0) {for(i=0;i<n;i++) if(P=B->dot.r->next) B->dot.r=P; else break;}
else {for(i=0;i>n;i--) if(P=B->dot.r->prev) B->dot.r=P; else break;}
B->dot.c=B->dot.r->from_tabexp(Jerry.x); y+=i;}
if(Jerry.buttons&1) (B->olddot-B->dot).color(White,Magenta);
B->dotcc=B->dotcc2=-1; B->display(); x=Jerry.x; P=B->dot.r;
if(P==B->text.next?:P==B->text.prev) Jerry.move(y,x); else y=Jerry.y;
Y: i=getkey(); if(i==-mousemove) goto Z; else nextch=i;}